var Reflect = require('./esprima');
var arrResults = new Array(0, 0, 0, 0, 0, 0, 0);

/*
var fs = require('fs');
var str1 = fs.readFileSync('1.js').toString();

var results = str1;

var ast = Reflect.parse(results);
variableFinder(ast);
*/

//Entrance Method
module.exports = {
	parseString: function (str)
	{
		arrResults = new Array(0, 0, 0, 0, 0, 0, 0);
		// get JavaScript Sections
		var ast = Reflect.parse(str);
		variableFinder(ast);
		return arrResults;
	}
};

function variableFinder(ast)
{
  var LenghtofAst = ast.body.length;
  for(var i = 0; i < LenghtofAst; i++)
  { ParseStatement(ast.body[i]); }
}	

function ForParser(ast)
{
  ParseExpression(ast.init);
  ParseExpression(ast.test);
  ParseExpression(ast.update);
  ParseStatement(ast.body);
}

function ParseStatement(ast)
{
  if(ast == null) 
  { }
  else{
    if(ast.type == "EmptyStatement")
    { }
  
    if(ast.type == "BlockStatement")
    { ParseStatement(ast.body); }

    if(ast.type == "ExpressionStatement")
    {   
    	//console.log( ast);
    	ParseExpression(ast.expression); }

    if(ast.type == "IfStatement")
    { ParseExpression(ast.test); ParseStatement(ast.consequent);  ParseStatement(ast.alternate); }

    if(ast.type == "LabeledStatement")
    {
      //console.log("Labeled Identifier: ", ast.label.name);
      ParseStatement(ast.body);  
    }

    if(ast.type == "WithStatement")
    { ParseExpression(ast.object); ParseStatement(ast.body); }

    if(ast.type == "TryStatement")
    { ParseStatement(ast.block); }
  
    if(ast.type == "WhileStatement")
    { ParseExpression(ast.test); ParseStatement(ast.body); }

    if(ast.type == "DoWhileStatement")
    { ParseStatement(ast.body); ParseExpression(ast.test); }

    if(ast.type == "ForStatement") 
    { ForParser(ast);  }

    if(ast.type == "ForInStatement")  
    { ForInParser(ast); }

    if(ast.type == "LetStatement") 
    { LetParser(ast);  ParseStatement(ast.body); }
 
    if(ast.type == "VariableDeclaration") { 
       ParseExpression(ast);
    }
 
    if(ast.type == "FunctionDeclaration")
    { functionDeclaration(ast); ParseStatement(ast.body); }
  }
}

function ParseExpression(ast) 
{  

  if(ast.type == "Identifier")
  {
    //console.log("Identifier: " + ast.name);
  }
  if(ast.type == "VariableDeclaration")
  { 
    variableDeclaration(ast); 
  }

  if(ast.type == "NewExpression")
  { 
    ParseExpression(ast.constructor); 
    var params = ast.arguments.length;
     for(var i = 0; i < params; i++)
     {
       ParseExpression(ast.arguments[i]);
     }
  }


  if(ast.type == "MemberExpression")
  {
	  ParseExpression(ast.object); 
  }

  if(ast.type == "UpdateExpression")
  {
    ParseExpression(ast.argument);
  }

  if(ast.type == "BinaryExpression")
  {
    if(ast.left.type == "Identifier" && ast.right.type != "Identifier")
     {
       //console.log("Identifier in Binary Expression" + ast);
     }
     else {
	if(ast.left.type == "Identifier") {
       		ParseExpression(ast.right);
	}
	if(ast.right.type == "Identifier") {
       		ParseExpression(ast.left);
	}
     }
     
  }

  if(ast.type == "LogicalExpression")
  {
     ParseExpression(ast.left);
     ParseExpression(ast.right);
  }

  if(ast.type == "ConditionalExpression")
  {
     ParseExpression(ast.left);
     ParseExpression(ast.right);
  }


  if(ast.type == "UnaryExpression")
  {
     ParseExpression(ast.argument);
  }
  if(ast.type == "AssignmentExpression")
  {
     if(ast.left.type == "Identifier")
     {
       //console.log("Identifier in Assignemnt Expression: " + ast.left.name);
     }
     else
       ParseExpression(ast.left);
     ParseExpression(ast.right);
  }
  if(ast.type == "CallExpression")
  {
	  
//		console.log(results[i].toString().match(/document\.write/gmi));//pattern);
//		console.log(results[i].toString().match(/document\.URL/gmi));
//		console.log(results[i].toString().match(/document\.location/gmi));
//		console.log(results[i].toString().match(/document\.referrer/gmi));
//		console.log(results[i].toString().match(/window\.location/gmi));
//		console.log(results[i].toString().match(/window\.localStorage/gmi));
     try
     {
    	 if(ast.callee.object.name == 'document' && ast.callee.property.name == 'write')
    	 {
    		 if(ast.arguments[0].type == 'Literal')
    			 console.log(ast.arguments[0].value);
    		 else
    			 {
        		 console.log("Danger a Document Write!!" + ast);
        		 arrResults[0]++;
    			 }
    			 

    	 }
    	 else if(ast.callee.object.name == 'document' && ast.callee.property.name == 'URL')
    	 {
    		 
    			 console.log("Danger a Document URL!!" + ast);
    			 arrResults[1]++;
    	 }
    	 else if(ast.callee.object.name == 'document' && ast.callee.property.name == 'location')
    	 {
    		 
    			 console.log("Danger a location !!" + ast);
    			 arrResults[2]++;
    	 }
    	 else if(ast.callee.object.name == 'document' && ast.callee.property.name == 'referrer')
    	 {
    		 
    			 console.log("Danger a referrer!!" + ast);
    			 arrResults[3]++;
    	 }
    	 else if(ast.callee.object.name == 'eval')
		 {
    		 console.log("Danger an Eval!!" + ast);
    		 arrResults[4]++;
		 }
    	 else if(ast.callee.object.name == 'window') 
    	 {
    		 console.log("Danger a window open!!" + ast);
    		 arrResults[5]++;
    	 }
    	 else if(ast.callee.object.name == 'elem'  && ast.callee.property.name == 'innerHTML') 
    	 {
    		 console.log("Danger a window open!!" + ast);
    		 arrResults[6]++;
    	 }
    	
     }
     catch(e)
     {
       //ignore	 
     }
    
     var params = ast.arguments.length;
     ParseExpression(ast.callee);
     
     for(var i = 0; i < params; i++)
     {
       ParseExpression(ast.arguments[i]);
     }
  }
  
  if(ast.type == "ArrayExpression")
  {
     var params = ast.elements.length;
     for(var i = 0; i < params; i++)
     {
       ParseExpression(ast.elements[i]);
     }
  }

  if(ast.type == "ObjectExpression")
  {
    var LenghtofAst = ast.properties.length;
    for(var i = 0; i < LenghtofAst; i++)
    { ParseExpression(ast.properties[i].value); }
     
  }

  if(ast.type == "FunctionExpression")
  {
     if(ast.id != null)
     {
       //console.log("Function Expression " + ast.id.name);
     }
     var params = ast.params.length;
     for(var i = 0; i < params; i++)
     {
         //console.log("Argument in Function Declaration: " +ast.params[i].name);
     }
     ParseStatement(ast.body);
  }
}

function functionDeclaration(ast)
{
   var params = ast.params.length;
   for(var i = 0; i < params; i++)
   {
      //console.log("Argument in Function: "+ast.params[i].name);
   }
}

function ForInParser(ast)
{
  ParseStatement(ast.left);
  ParseExpression(ast.right);
  ParseStatement(ast.body);
}

function variableDeclaration(obj)
{
  var sizeofDecl = obj.declarations.length;
  for(var j = 0; j < sizeofDecl; j++)
  {
     //console.log("Variable Declaration: " + obj.declarations[j].id.name);
  }
}
